
package com.dreamfish.record;

import android.util.Log;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


/** @author chenmy0709
 * @version V001R001C01B001 */
public class PcmToWav
{
	/** 合并多个pcm文件为一个wav文件
	 * 
	 * @param filePathList
	 *            pcm文件路径集合
	 * @param destinationPath
	 *            目标wav文件路径
	 * @return true|false */
	public static boolean mergePCMFilesToWAVFile(List<String> filePathList, String destinationPath)
	{
		File[] file = new File[filePathList.size()];
		byte buffer[] = null;
		
		int TOTAL_SIZE = 0;
		int fileNum = filePathList.size();
		
		for (int i = 0; i < fileNum; i++)
		{
			file[i] = new File(filePathList.get(i));
			TOTAL_SIZE += file[i].length();
		}
		
		// 填入参数，比特率等等。这里用的是16位单声道 8000 hz
		WaveHeader header = new WaveHeader();
		// 长度字段 = 内容的大小（TOTAL_SIZE) +
		// 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
		header.fileLength = TOTAL_SIZE + (44 - 8);
		header.FmtHdrLeth = 16;
		header.BitsPerSample = 16;
		header.Channels = 2;
		header.FormatTag = 0x0001;
		header.SamplesPerSec = 8000;
		header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
		header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
		header.DataHdrLeth = TOTAL_SIZE;
		
		byte[] h = null;
		try
		{
			h = header.getHeader();
		}
		catch (IOException e1)
		{
			Log.e("PcmToWav", e1.getMessage());
			return false;
		}
		
		if (h.length != 44) // WAV标准，头部应该是44字节,如果不是44个字节则不进行转换文件
			return false;
		
		//先删除目标文件
		File destfile = new File(destinationPath);
		if (destfile.exists()) destfile.delete();
		
		//合成所有的pcm文件的数据，写到目标文件
		try
		{
			buffer = new byte[1024 * 4]; // Length of All Files, Total Size
			InputStream inStream = null;
			OutputStream ouStream = null;
			
			ouStream = new BufferedOutputStream(new FileOutputStream(destinationPath));
			ouStream.write(h, 0, h.length);
			for (int j = 0; j < fileNum; j++)
			{
				inStream = new BufferedInputStream(new FileInputStream(file[j]));
				int size = inStream.read(buffer);
				while (size != -1)
				{
					ouStream.write(buffer);
					size = inStream.read(buffer);
				}
				inStream.close();
			}
			ouStream.close();
		}
		catch (FileNotFoundException e)
		{
			Log.e("PcmToWav", e.getMessage());
			return false;
		}
		catch (IOException ioe)
		{
			Log.e("PcmToWav", ioe.getMessage());
			return false;
		}
		clearFiles(filePathList);
		Log.i("PcmToWav", "mergePCMFilesToWAVFile  success!" + new SimpleDateFormat("yyyy-MM-dd hh:mm").format(new Date()));
		return true;
		
	}
	
	/** 将一个pcm文件转化为wav文件
	 * 
	 * @param pcmPath
	 *            pcm文件路径
	 * @param destinationPath
	 *            目标文件路径(wav)
	 * @param deletePcmFile
	 *            是否删除源文件
	 * @return */
	public static boolean makePCMFileToWAVFile(String pcmPath, String destinationPath, boolean deletePcmFile)
	{
		byte buffer[] = null;
		int TOTAL_SIZE = 0;
		File file = new File(pcmPath);
		if (!file.exists()) { return false; }
		TOTAL_SIZE = (int) file.length();
		// 填入参数，比特率等等。这里用的是16位单声道 8000 hz
		WaveHeader header = new WaveHeader();
		// 长度字段 = 内容的大小（TOTAL_SIZE) +
		// 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
		header.fileLength = TOTAL_SIZE + (44 - 8);
		header.FmtHdrLeth = 16;
		header.BitsPerSample = 16;
		header.Channels = 2;
		header.FormatTag = 0x0001;
		header.SamplesPerSec = 8000;
		header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
		header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
		header.DataHdrLeth = TOTAL_SIZE;
		
		byte[] h = null;
		try
		{
			h = header.getHeader();
		}
		catch (IOException e1)
		{
			Log.e("PcmToWav", e1.getMessage());
			return false;
		}
		
		if (h.length != 44) // WAV标准，头部应该是44字节,如果不是44个字节则不进行转换文件
			return false;
		
		//先删除目标文件
		File destfile = new File(destinationPath);
		if (destfile.exists()) destfile.delete();
		
		//合成所有的pcm文件的数据，写到目标文件
		try
		{
			buffer = new byte[1024 * 4]; // Length of All Files, Total Size
			InputStream inStream = null;
			OutputStream ouStream = null;
			
			ouStream = new BufferedOutputStream(new FileOutputStream(destinationPath));
			ouStream.write(h, 0, h.length);
			inStream = new BufferedInputStream(new FileInputStream(file));
			int size = inStream.read(buffer);
			while (size != -1)
			{
				ouStream.write(buffer);
				size = inStream.read(buffer);
			}
			inStream.close();
			ouStream.close();
		}
		catch (FileNotFoundException e)
		{
			Log.e("PcmToWav", e.getMessage());
			return false;
		}
		catch (IOException ioe)
		{
			Log.e("PcmToWav", ioe.getMessage());
			return false;
		}
		if (deletePcmFile)
		{
			file.delete();
		}
		Log.i("PcmToWav", "makePCMFileToWAVFile  success!" + new SimpleDateFormat("yyyy-MM-dd hh:mm").format(new Date()));
		return true;
		
	}
	
	/** 清除文件
	 * 
	 * @param filePathList */
	private static void clearFiles(List<String> filePathList)
	{
		for (int i = 0; i < filePathList.size(); i++)
		{
			File file = new File(filePathList.get(i));
			if (file.exists())
			{
				file.delete();
			}
		}
	}
}
